import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.texture.TextureIO;
/*
 * Tomer Nuni 300585312
 * Idan Meshita 300043726
 */
public class Navigation3D implements GLEventListener, KeyListener {
    float rotateT = 0.0f;
    static GLU glu = new GLU();
    static GLCanvas canvas = new GLCanvas();
    static Frame frame = new Frame("Jogl 3D Shape/Rotation");
    static Animator animator = new Animator(canvas);
    double	alpha = 90, alpha_step = 5;
    double	beta = 0, beta_step = 5;
    double	eyeX=500, eyeY=150, eyeZ=500;
    double	upX=0, upY=1, upZ=0;
    double	step=20;
   

	private MapBuilder mapBuilder;
	
	private TableBuilder tableBuilder;
	private BenchBuilder bench1;
	private BenchBuilder bench2;
	
	public Navigation3D() {
		mapBuilder= new MapBuilder();
		tableBuilder = new TableBuilder();
		bench1 = new BenchBuilder();
		bench2 = new BenchBuilder();
	}
    
	public double SIN(double x)
	{
		return java.lang.Math.sin(x*3.14159/180);
	}
	
	public double COS(double x)
	{
		return java.lang.Math.cos(x*3.14159/180);
	}
	
    public void display(GLAutoDrawable gLDrawable) {
		final GL gl = gLDrawable.getGL();
		gl.glClear(GL.GL_COLOR_BUFFER_BIT);
		gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
		gl.glLoadIdentity();
		//set the camera view
		glu.gluLookAt(eyeX,eyeY,eyeZ,eyeX+(COS(beta)*COS(alpha)),eyeY+SIN(beta),eyeZ+(COS(beta)*SIN(alpha)),upX,upY,upZ);  
		mapBuilder.draw(gl);
		
		gl.glPushMatrix();
		gl.glTranslated(600, 0, 480);
		tableBuilder.draw(gl);
		gl.glPopMatrix();
		
		gl.glPushMatrix();
		gl.glTranslated(600, 0, 350);
		bench1.draw(gl);
		gl.glPopMatrix();
		
		
		gl.glPushMatrix();
		gl.glTranslated(600, 0, 910);
		bench2.draw(gl);
		gl.glPopMatrix();
		

    }
 


    public void displayChanged(GLAutoDrawable gLDrawable, 
			       boolean modeChanged, boolean deviceChanged) {
    }
 
    public void init(GLAutoDrawable gLDrawable) {
		GL gl = gLDrawable.getGL();
		gl.glShadeModel(GL.GL_SMOOTH);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glClearDepth(1.0f);
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glDepthFunc(GL.GL_LEQUAL);
		gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
		//init texture
        gl.glEnable(GL.GL_TEXTURE_2D);
        loadTexture();
       
		mapBuilder.buildMap(gl);

		tableBuilder.buildTable(gl);
		tableBuilder.buildTable(gl);
		bench1.buildTable(gl);
		bench2.buildTable(gl);
		gLDrawable.addKeyListener(this);
    }
 
    private void loadTexture() {
    	 try {
     		String filename="wall.jpg"; // the FileName to open
     		mapBuilder.wallTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
             e.printStackTrace();
             throw new RuntimeException(e);
         }
         try {
     		String filename="celling.jpg"; // the FileName to open
     		mapBuilder.cellingTexture=TextureIO.newTexture(new File( filename ),true);
     		
         } catch (IOException e) {
             e.printStackTrace();
             throw new RuntimeException(e);
         }
         try {
     		String filename="floor.jpg"; // the FileName to open
     		mapBuilder.floorTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
             e.printStackTrace();
             throw new RuntimeException(e);
         }
         
         
         // Table textures
         try {
        	 String filename="wood.jpg"; // the FileName to open
        	 tableBuilder.legsTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace(); 
        	 throw new RuntimeException(e);
         }
         try {
        	 String filename="wood.jpg"; // the FileName to open
        	 tableBuilder.topTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
         try {
        	 String filename="wood.jpg"; // the FileName to open
        	 tableBuilder.frameTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }

      // bench1 textures
         try {
        	 String filename="wood.jpg"; // the FileName to open
        	 bench1.legsTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
         try {
        	 String filename="benchTop.jpg"; // the FileName to open
        	 bench1.topTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
         try {
        	 String filename="benchTop.jpg"; // the FileName to open
        	 bench1.frameTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
         
      // bench2 textures
         try {
        	 String filename="wood.jpg"; // the FileName to open
        	 bench2.legsTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
         try {
        	 String filename="celling.jpg"; // the FileName to open
        	 bench2.topTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
         try {
        	 String filename="celling.jpg"; // the FileName to open
        	 bench2.frameTexture=TextureIO.newTexture(new File( filename ),true);
         } catch (IOException e) {
        	 e.printStackTrace();
        	 throw new RuntimeException(e);
         }
	}

	public void reshape(GLAutoDrawable gLDrawable, int x, 
			int y, int width, int height) {
		GL gl = gLDrawable.getGL();
		if(height <= 0) {
		    height = 1;
		}
		float h = (float)width / (float)height;
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		glu.gluPerspective(50.0f, h, 1.0, 10000.0);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
    }
 
    public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
		    exit();
		}
		
		if(e.getKeyCode() == KeyEvent.VK_UP) {
			if (beta%90==0&& beta%180!=0 ){
				upY=-1*upY;
				alpha_step=-alpha_step;
			}
			beta+= beta_step;	
			
			

		}
		if(e.getKeyCode() == KeyEvent.VK_DOWN) {
			
			if (beta%90==0&& beta%180!=0 ){
				upY=-1*upY;
			}
			beta-= beta_step;	
			
			
		}
		if(e.getKeyCode() == KeyEvent.VK_LEFT) {
			
				alpha -= alpha_step;
			
				
		}
		if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
				alpha += alpha_step;
			
		}
		if(e.getKeyCode() =='W'||e.getKeyCode() =='w') {
		    eyeX += step*COS(beta)*COS(alpha);
		    eyeY += step*SIN(beta);
		    eyeZ += step*COS(beta)*SIN(alpha);
		}
		if(e.getKeyCode() =='S'||e.getKeyCode() =='s') {
		    eyeX -= step*COS(beta)*COS(alpha);
		    eyeY -= step*SIN(beta);
		    eyeZ -= step*COS(beta)*SIN(alpha);
		}
		if(e.getKeyCode() =='a'||e.getKeyCode() =='A') {
		    eyeX -= step*COS(90+alpha);
		    eyeZ -= step*SIN(90+alpha);

		}
		if(e.getKeyCode() =='d'||e.getKeyCode() =='D') {
		    eyeX += step*COS(90+alpha);
		    eyeZ += step*SIN(90+alpha);
		}
    }
 
    public void keyReleased(KeyEvent e) {
    }
 
    public void keyTyped(KeyEvent e) {
    }
 
    public static void exit(){
		animator.stop();
		frame.dispose();
		System.exit(0);
    }
 
    public static void main(String[] args) {
		canvas.addGLEventListener(new Navigation3D());
		frame.add(canvas);
		frame.setSize(640, 480);
//		frame.setUndecorated(true);
//		frame.setExtendedState(Frame.MAXIMIZED_BOTH);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
			    exit();
			}
		    });
		frame.setVisible(true);
		animator.start();
		canvas.requestFocus();
    }
}
